package com.leyou.system.service;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.leyou.common.domain.PageResult;
import com.leyou.common.exception.domain.ExceptionEnum;
import com.leyou.common.exception.domain.LyException;
import com.leyou.common.utils.BeanHelper;
import com.leyou.system.domain.Permission;
import com.leyou.system.dto.PermissionDTO;
import com.leyou.system.mapper.PermissionMapper;
import com.leyou.system.vo.PermissionVo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * Date: 2019/11/28
 * Author: L
 * Description: 权限service
 */
@Service
public class PermissionService {

    // 注入mapper
    @Autowired
    private PermissionMapper permissionMapper;

    /**
     * 查询权限列表
     */
    public PageResult<PermissionDTO> PermissionPageQuery(Integer page, Integer rows, String key, String sortBy, Boolean desc,Integer parentId) {
        // 封装分页条件
        PageHelper.startPage(page, rows);
        // 创建一个封装条件的对象
        Example example = new Example(Permission.class);
        Example.Criteria criteria = example.createCriteria();
        //根据父id查询
        criteria.andEqualTo("parentId",parentId);
        // 判断查询条件是否有值
        if (!StringUtils.isEmpty(key)) {
            //拿搜索关键字去模糊查询name名称
            criteria.andLike("title", "%" + key + "%");
        }

        // 判断排序字段是否有值
        if (!StringUtils.isEmpty(sortBy)) {
            //setOrderByClause中可以写原始sql语句，比如： select * from xx order by a desc
            example.setOrderByClause(sortBy + " " + (desc ? "DESC" : "ASC"));
        }


        // 查询数据库得到权限集合
        List<Permission> permissionList = permissionMapper.selectByExample(example);
        // 判断是否有数据
        if (CollectionUtils.isEmpty(permissionList)) {
            throw new LyException(ExceptionEnum.PERMISSION_NOT_FOUND);
        }

        // 封装成pageHelper的分页对象
        PageInfo<Permission> pageInfo = new PageInfo<>(permissionList);
        // 获取pageHelper的分页对象中的list
        List<Permission> permissions = pageInfo.getList();
        // 转换成DTO
        List<PermissionDTO> permissionDTOs = BeanHelper.copyWithCollection(permissions, PermissionDTO.class);
        // 封装自定义的分页对象
        PageResult<PermissionDTO> pageResult = new PageResult<>(pageInfo.getTotal(), pageInfo.getPages(), permissionDTOs);
        // 返回数据
        return pageResult;
    }

    /**
     * 根据父id查询权限
     * @param pid
     * @return
     */
    public List<PermissionDTO> queryPermissionByPid(Integer pid) {
        // 创建权限对象并给parentId赋值
        Permission record = new Permission();
        record.setParentId(pid);
        // 查询数据库
        List<Permission> permissionList = permissionMapper.select(record);
        // 判断是否有值
        if (CollectionUtils.isEmpty(permissionList)) {
            throw new LyException(ExceptionEnum.PERMISSION_NOT_FOUND);
        }
        // 装换成DTO对象
        List<PermissionDTO> permissionDTOS = BeanHelper.copyWithCollection(permissionList, PermissionDTO.class);
        //封装 isParent
        permissionDTOS.forEach(permissionDTO -> {
            if(permissionDTO.getParentId() == 0){
                permissionDTO.setIsParent(true);
            }
        });
        // 返回数据
        return permissionDTOS;
    }

    /**
     * 根据角色id查询权限,但是前端参数显示的是pid
     * @param rid
     * @return
     */
    public List<PermissionDTO> queryByRoleId(Integer rid) {
        // 查询数据库
        List<Permission> permissions = permissionMapper.queryByRoleId(rid);
        // 判断集合是否有值
        if (CollectionUtils.isEmpty(permissions)) {
            throw new LyException(ExceptionEnum.PERMISSION_NOT_FOUND);
        }
        // 转换为PermissionDTO
        List<PermissionDTO> permissionDTOList = BeanHelper.copyWithCollection(permissions, PermissionDTO.class);
        //根据二级权限，查询一级权限
        permissions.forEach(permission -> {
            Permission permission1 = permissionMapper.selectByPrimaryKey(permission.getParentId());
            PermissionDTO permissionDTO1 = BeanHelper.copyProperties(permission1, PermissionDTO.class);
            if (!permissionDTOList.contains(permissionDTO1)) {
                permissionDTOList.add(permissionDTO1);
            }
        });
        // 根据parentId分组收集permissionDTOList
        Map<Integer, List<PermissionDTO>> map =
                permissionDTOList.stream().collect(Collectors.groupingBy(PermissionDTO::getParentId));

        //一级菜单列表
        List<PermissionDTO> permissionDTOList1 = map.get(0);

        permissionDTOList1.forEach(permissionDTO -> {
            // 一级菜单下的二级菜单
            List<PermissionDTO> permissionDTOList2 = map.get(permissionDTO.getId());
            permissionDTO.setItemList(permissionDTOList2);
        });

        return permissionDTOList1;
    }

    /**
     * 查询所有权限
     * @return
     */
    public List<PermissionDTO> queryAll() {
        List<Permission> permissions = permissionMapper.selectAll();
        List<PermissionDTO> permissionDTOList = BeanHelper.copyWithCollection(permissions, PermissionDTO.class);
        return permissionDTOList;
    }

    /**
     * 查询所有的一级菜单
     * @param parentId
     * @return
     */
    public List<PermissionDTO> findAllPermissionByParentId(Integer parentId) {
        Permission permission = new Permission();
        permission.setParentId(parentId);
        List<Permission> list = permissionMapper.select(permission);
        if (list.size()==0){
            throw new LyException(ExceptionEnum.PERMISSION_NOT_FOUND);
        }
        List<PermissionDTO> dtos = BeanHelper.copyWithCollection(list, PermissionDTO.class);
        return dtos;
    }


    /**
     * 新增菜单
     * @param permissionDTO
     */
    public void addPermission(PermissionDTO permissionDTO) {
        Permission permission = BeanHelper.copyProperties(permissionDTO, Permission.class);
        List<PermissionDTO> parent = permissionDTO.getParent();
        if (!CollectionUtils.isEmpty(parent)){
            permission.setParentId(parent.get(0).getId());
        }

        //判断是否是一级菜单
        if (permissionDTO.getIsParent()){
            permission.setParentId(0);
        }
        //添加菜单
        int count = permissionMapper.insertSelective(permission);
        if (count!=1){
            throw new LyException(ExceptionEnum.INSERT_OPERATION_FAIL);
        }
    }

    /**
     * 根据id查询菜单
     * @param id
     * @return
     */
    public PermissionDTO findPermissionById(Integer id) {
        Permission permission = permissionMapper.selectByPrimaryKey(id);

        if (permission==null){
            throw new LyException(ExceptionEnum.PERMISSION_NOT_FOUND);
        }

        PermissionDTO permissionDTO = BeanHelper.copyProperties(permission, PermissionDTO.class);
        if (permission.getParentId()==0){
            permissionDTO.setIsParent(true);
        }else {
            permissionDTO.setIsParent(false);
            List<PermissionDTO> list = queryPermissionByPid(permission.getParentId());
            permissionDTO.setParent(list);
        }
        return permissionDTO;
    }

    /**
     * 向角色权限表中添加数据
     * @param roleId
     * @param pids
     */
    public void insertRoleAndPermission(Integer roleId, List<Integer> pids) {
        // 遍历权限id集合
        pids.forEach(permissionId -> {
            permissionMapper.insertRoleAndPermission(roleId, permissionId);
        });
    }


    /*
    根据用户id查询用户的菜单列表
     */
    public List<PermissionVo> findMenus(Integer id) {

        return null;
    }


    public List<PermissionVo> findPermissionByUserId(Integer uid) {
        List<Permission> plist = permissionMapper.findPermissionFatherByUserId(uid);
        //父权限对象
        List<PermissionVo> plistVo = BeanHelper.copyWithCollection(plist, PermissionVo.class);

        //子权限对象
        List<Permission> list = permissionMapper.findPermissionByUserId(uid);
        List<PermissionVo> listVo = BeanHelper.copyWithCollection(list, PermissionVo.class);

        //遍历list下的所有父权限
        for (PermissionVo permissionDTO : plistVo) {
            //查出父权限的id
            Integer id = permissionDTO.getId();

            List<PermissionVo> clist = new ArrayList<>();

            //遍历所有子权限
            for (PermissionVo permission : listVo) {
                //获取子权限的父id
                Integer parentId = permission.getParentId();
                if (parentId==id){
                    //相等的话就插入
                    clist.add(permission);
                }
            }
            permissionDTO.setItems(clist);
        }

        return plistVo;
    }
}
